UART2 auf dem STM8S105


Zur Verwendung der UART2 auf dem STM8S105 werden folgende Vorbereitungen getroffen um Daten übertragen zu können.

Im Segment `ram0` (der Bereich des SRAMs der durch ein Byte adressiert werden kann) werden folgende Variablen angelegt. TXCHAR und RXCHAR sind Zwischenspeicher für die aktuellen Zeichen die geschrieben oder gelesen werden sollen. Das Flag RXSTAT zeigt den Status des Empfangspuffers an (leer oder mindestens ein Zeichen wartet auf Verarbeitung).

;--------------------------------------------------------------------------------------
      segment 'ram0'
;--------------------------------------------------------------------------------------

TXCHAR        ds.b         ; UART Transmit Character Buffer
RXCHAR        ds.b         ; UART Receive Character Buffer
RXSTAT        ds.b         ; UART Receive Buffer empty (= 0)

 

Im Segment `ram1` werden die Pointer angelegt die auf die beiden zirkularen 64 Byte Puffer für Senden (UTX) bzw. für Empfangen (URX) zeigen. Dabei gibt es jeweils einen Pointer der auf das nächste freie Byte (Write) und Einen der auf das nächste zu lesende Byte (Read) zeigt. Die Variable „UART_ERR“ ist ein Status-Byte das eventuelle Fehler anzeigt (Puffer Überlauf).

;--------------------------------------------------------------------------------------
      segment'ram1'
;--------------------------------------------------------------------------------------

UTX_WRT      ds.b         ; WRITE pointer (Byte) to Transmit Buffer
UTX_RD       ds.b         ; READ pointer (Byte) from Transmit Buffer
URX_WRT      ds.b         ; WRITE pointer (Byte) to Receive Buffer
URX_RD       ds.b         ; READ pointer (Byte) from Receive Buffer
UART_ERR     ds.b         ; UART Error register (Bit0 = Receive Buffer OVL)
                          ;             (Bit1 = Transmit Buffer OVL)

 

Der eigentliche Sendepuffer (UTX_BUF) wird durch die “segment 64” Direktive auf eine 64 Byte Grenze justiert was das Zeigerhandling vereinfacht und einen Pointerüberlauf vehindert. Der zirkulare Puffer wird im `ram1` Segment angelegt.

 

;--------------------------------------------------------------------------------------
      segment 64  'ram1'
;--------------------------------------------------------------------------------------

UTX_BUF      ds.b   64     ; UART Transmit Buffer 64 Byte / Modulo 64

 

Der Empfangspuffer (URX_BUF) wird auch durch die “segment 64” Direktive auf eine 64 Byte Grenze justiert was ebenfalls das Zeigerhandling vereinfacht und einen Pointerüberlauf vehindert. Der zirkulare Puffer wird im `ram1` Segment angelegt.

 

;--------------------------------------------------------------------------------------
      segment 64  'ram1'
;--------------------------------------------------------------------------------------

URX_BUF      ds.b   64     ; UART Receive Buffer 64 Byte / Modulo 64

Initialisierung Hardware und Variablen

Mit diesen Deklarationen sind die nötigen Variablen für den Betrieb der UART aufgesetzt so dass im nächsten Schritt die Initialisierung der UART Hardware erfolgen kann. Zu Beginn der Programmverarbeitung erhalten die diversen UART2 Register durch eine Reihe von Instruktionen die aus dem Code-Segment `rom` ausgeführt werden, ihre Werte. Die für die UART definierten Variablen müssen ebenfalls auf ihre Anfangswerte gesetzt werden.

 

;--------------------------------------------------------------------------------------
      segment 'rom'
;--------------------------------------------------------------------------------------

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Init UART2     (Initialisierung)    115 kBaud, 8 Bit, 1 Stop-Bit
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ld    A,#$F1            ;
ld    TXCHAR,A          ;
 
ld    A,#$0B            ; Lade BAUD Rate Wert für BRR2
ld    UART2_BRR2,A      ; Setze BAUD Rate Register 2
ld    A,#$08            ; Lade BAUD Rate Walue für BRR1
ld    UART2_BRR1,A      ; Setze BAUD Rate Register 1
bres  UART2_CR1,#6      ; Konfiguriere UART für „8 Bit“ Daten
     
clr   A                 ; Lade 0x00 in Akku
ld    RXSTAT,A          ; Receive Status = 0 (kein Zeichen
                        ; im Empfangspuffer)
ld    URX_RD,A          ; Setze URX_RD Pointer auf “0“
ld    URX_WRT,A         ; Setze URX_WRT Pointer auf “0”
ld    UTX_RD,A          ; Setze UTX_RD Pointer auf “0”
ld    UTX_WRT,A         ; Setze UTX WRT Pointer auf “0”
ld    UART2_CR3,A       ; Konfiguriere “1 Stop Bit”
bres  UART2_CR1,#5      ; UART2 Funktion freigeben
bset  UART2_CR2,#3      ;
bset  UART2_CR2,#5      ; Schalte “UART2 Receive Interrupt” frei
bset  UART2_CR2,#2      ; Empfang von Daten freigeben
                        ; UART Kommunikation aktiv
call  TX_UART           ; Sende eventuell im UTX-Puffer vorhandene
                        ; Zeichen über die UART
call  Read_Command      ; Lese eventuell Zeichen aus dem
                        ; URX-Puffer
 

 

Die beiden Register UART2_BRR1 und UART2_BRR2 setzen die Baud-Rate für die UART2. Der benutzte Wert bezieht sich auf eine STM8 Clock von 16 MHz. Die Reihenfolge der Registerzugriffe sollte eingehalten werden. Im UART2_CR1 (UART2 Configuration Register 1) wird Bit 6 gesetzt um eine 8-Bit Übertragung zu definieren.

Danach werden die Pointer für den Empfangs- und den Sende-Puffer initialisiert und das Empfangs-Status-Flag

gelöscht (kein Zeichen im Puffer).

Erst im Anschluss wird das UART2_CR3 (Configuration Register 3) auf 0x00h gestzt und damit die Übertragung mit einem STOP-Bit initialsiert.

Schliesslich werden in den Registern UART2_CR1 und UART2_CR2 die nötigen Bits gesetzt/rückgesetzt um die UART2 freizugeben und den Interrupt für empfangene Zeichen der UART2 zu aktivieren.

Schliesslich werden zur exakten Synchronisation die beiden (im weiteren Verlauf beschriebenen) Subroutinen

„TX_UART“ und „Read_Command“ aufgerufen. Diese werden zum aktuellen Zeitpunkt keine Charakter finden aber sicherstellen dass die beiden Ringpuffer im Zustand „leer“ sind.

Im weiteren Verlauf werden nun die Subroutinen beschrieben die von der eigentlichen Anwendung aufgerufen werden um Daten über die UART2 in beide Richtungen übertragen zu können. Diese Subroutinen befinden sich natürlich auch im Segment `rom` und stehen über ihre Einsprungadressen für die Applikation zur Verfügung.

Zeichen senden

Die Subroutine „Send_Char“ speichert das Zeichen das in der Variablen „TXCHAR“ bereitsteht im Ring-Puffer an der nächsten freien Stelle, insofern eine Stelle im Puffer frei ist! Wird keine freie Stelle gefunden so wird das Zeichen aus „TX_BUF“ verworfen und das Bit 1 in „UART_ERR“ gesetzt, welches einen Überlauf signalisiert.

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Send CHARACTER(Subroutine)  -  Transfer single Character to UTX_BUF
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; This subroutine writes a character stored in TXCHAR (RAM) to the Transmit
; Buffer" at the next free location (inc UTX_WRT). The Buffer Pointers are
; checked and in case the "Transmit Buffer" is full (overflow), the
; character is dropped and instead UART_ERR Bit 1 is set. The "Transmit
; Buffer" is a circular 64 Byte Buffer, aligned to a 64 Byte boundary
; (segment 64).

Send_Char

   ld    A,UTX_WRT      ; Lade UTX-Write Pointer in den Akku
   inc   A              ; Increment UTX_WRT Pointer auf die nächste
                        ; mögliche Position
   and   A,#$3F         ; Maskiere UTX_WRT Pointer auf 6 Bit (Modulo 64)
   cp    A,UTX_RD       ; Vergleiche mit aktuellem UTX_RD pointer
   jreq  Send_Ovl       ; “IF:” nächster UTX_WRT Pointer = UTX_RD
                        ; Pointer > Overflow
cont_send
   clr   A              ; Lade Akku mit "0"
   ld    XH,A           ; Lade X-High Byte mit “0”
   ld    A,UTX_WRT      ; Lade UTX_WRT Pointer (offset) in ACCU
   ld    XL,A           ; Lade X-Low Byte = UTX_WRT
   ld    A,TXCHAR       ; Lade zu sendendes Zeichen in Akku
   ld    (UTX_BUF,X),A  ; Lade Zeichen in UTX Puffer + Offset
   ld    A,UTX_WRT      ; Lade UTX_WRT Puffer Pointer
   inc   A              ; Incrementiere UTX_WRT Puffer Pointer
   and   A,#$3F         ; Maskiere UTX_WRT auf 6 Bit (Modulo 64)
   ld    UTX_WRT,A      ; neuen UTX_WRT Pointer abspeichern
   jp    End_CharSend   ; Beende Zeichen Transfer

Send_Ovl
   bset  UART_ERR,#1    ; Setze UTX_BUF Überlauf Flag
   call  TX_UART        ; Initiiere UART Übertragung
   jra   cont_send      ; Aktualisiere Pointer

End_CharSend:
   Ret                  ; Beende Subroutine

 

Send-Char“ wird von der Applikation jedes mal aufgerufen nachdem die Anwendung ein Zeichen in der Variablen „TXCHAR“ zum Senden plaziert hat.

Zeichen lesen

Äquivalent zum Senden eines Zeichens erfüllt die Subroutine „Read_Char“ die Aufgabe das nächste („älteste“) Zeichen im Empfangs-Puffer (Ringpuffer = FIFO) auszulesen und in der Variablen RXCHAR zur Verfügung zu stellen.

Das Pointer-Management stellt sicher dass der Lese-Pointer aktualisiert wird und das Status-Byte RXSTAT den aktuellen Zustand nach dem Auslesen wiedergibt (leer oder weitere Zeichen vorhanden).

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Read CHARACTER(Subroutine)  -  Read single Character from URX_BUF
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

; This subroutine reads a character from the "Receive Buffer" and stores
; it in RXCHAR (RAM). If the "Receive Buffer" is not empty, RXSTAT (RAM)
; is set 0x0Fh.
; If a character is read, the receive read pointer URX_RD is incremented
; (MOD64)and if the "Receive Buffer" is empty, RXSTAT (RAM) is cleared
; (0x00h), the URX_RD remains unchanged. The "Receive Buffer" is a 64
; Byte Buffer aligned to a 64 Byte border (segment 64).

Read_Char
   pushw X               ; Sichere “X-Register” auf dem Stack
   ld  A,URX_RD          ; Lade URX_RD Pointer für nächstes Zeichen
   and   A,#$3F          ; Maskiere URX_RD Pointer auf 6 Bit (Mod 64)
   ld    URX_RD,A        ; URX_RD Pointer abspeichern
   ld    A,URX_WRT       ; Lade URX_WRT Pointer in Akku
   and   A,#$3F          ; Maskiere URX_WRT Pointer auf 6 Bit(Mod 64)
   ld    URX_WRT,A       ; URX_WRT Pointer abspeichern
   ld    A,URX_RD        ; Lade URX_RD in Akku
   cp    A,URX_WRT       ; Vergleiche mit URX_WRT Pointer
   jreq  Rx_Buff_Empty   ; “IF” Read-Pointer = Write-Pointer (equal
                         ; bedeuted, Puffer ist leer
   ld    A,#$0F          ; “else” Read-Buffer ist nicht leer
   ld    RXSTAT,A        ; Setze RXSTAT to 0x0Fh = not empty
   clr   A               ; Lade Akku mit “0”
   ld    XH,A            ; Lade X-Register high mit “0”
   ld    A,URX_RD        ; Lade Akku mit URX_RD Pointer
   and   A,#$3F          ; Maskiere URX_RD Pointer auf 6 Bit (Mod 64)
   ld    XL,A            ; Lade XL-register with URX_RD Pointer
   ld    A,(URX_BUF,X)   ; Lese Zeichen aus dem URX_BUF
   ld    RXCHAR,A        ; Schreibe das gelesene Zeichen in RXCHAR
   inc   URX_RD          ; Incrementiere  URX_RD Pointer
   jra   Rx_Buff_Read    ; “GOTO:” Rx_Buff_Read (Beenden)

Rx_Buff_Empty
   clr   A               ; Lade Akku mit “0”
   ld    RXSTAT,A        ; Setze RXSTAT to 0x00h = Buffer empty

Rx_Buff_Read
   popw  X               ; X-Register Inhalt aus Stack zurückladen

   ret

 

Die Subroutine “Read_Char” wird von der Anwendung aufgerufen, die die empfangenen Zeichen direkt weiterverarbeitet, um das nächste anstehende Zeichen aus dem Empfangspuffer auszulesen  und entsprechend der Aufgabe des Programms zu verwenden.

Sende Zeichen über UART2

Die beiden bisher besprochenen Subroutinen “Send_Char” und “Read_Char” stellen die Schnittstelle von der Applikation zu den zirkularen Puffern dar aber keines der Zeichen wurde dabei zwischen den Puffern und der UART2 Hardware übertragen.

Diese Aufgabe übernimmt in der Senderichtung die Subroutine „TX_UART“ die alle, aktuell im Sende-Puffer befindlichen Zeichen über die UART sendet.

TX_UART“ ist eine Task die zyklisch (im verwendeten Beispiel alle 200 ms) aufgerufen wird um den Sendepuffer zu übertragen.

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; TX UART(Subroutine) -  send Character buffer over UART2
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

TX_UART
   ld    A,UTX_WRT             ; Lade UTX_WRT Pointer (nächste freie WRITE
                               ;Speicherzelle)
   cp    A,UTX_RD              ;Vergleiche WRITE mit READ Pointer
   jreq  TxUart_Done           ;”IF:” Vergleich = 0 (empty), beende Transmit
   btjf  UART2_SR,#6,TX_UART   ;”ELSE:” teste:UART ist empfangsbereit
   ld    A,UTX_RD              ;Lade UTX_RD Pointer in Akku
   ld    XL,A                  ;Lade READ pointer in X_Register Low
   clr   A                     ;Akku = “0”
   ld    XH,A                  ;Lade 0x00h in X-Register High
   ld    A,(UTX_BUF,X)         ;Lade nächstes zu übertragendes Zeichen
   ld    UART2_DR,A            ;Lade Zeichen in UART Transmit Register
   clr   A                     ;Akku = “0”
   ld    (UTX_BUF,X),A         ;lösche das übertragene Zeichen aus dem
                               ;Puffer
   ld    A,UTX_RD              ;Lade UTX_RD Pointer in Akku
   inc   A                     ;Increment READ pointer !!!
   and   A,#$3F                ;Maskiere UTX_RD Pointer auf 6 Bit (Mod 64)
   ld    UTX_RD,A              ;Neuen UTX_RD Pointer abspeichern
   jra   TX_UART               ;“GOTO:” TX_UART (Schleife)

TxUart_Done
   Ret                         ;Beende Subroutine

 

Das Senden von Zeichen wird zeitlich von der Software bestimmt und kann entsprechend kontrolliert werden. Die Task „TX_UART“ überträgt die im Sende-Puffer bereitstehenden Zeichen zu dem Zeitpunkt zu dem die Funktion aufgerufen wird. Geschieht das häufig genug besteht keine Gefahr dass Zeichen verloren gehen oder überschrieben werden.

Anders verhält sich das System in der Empfangsrichtung da die ankommenden Zeichen in der UART Hardware asynchron eingehen und mangels eines FIFOs sofort aus dem UART H/W Puffer ausgelesen werden müssen. Um zu vermeiden dass ein Zeichen durch überschreiben verloren geht muss das System eine kurze Task unmittelbar starten, die das empfange Zeichen aus dem UART H/W Puffer ausliest und in den UART-Empfangspuffer einträgt.

Empfange Zeichen über UART2 (Interrupt Subroutine)

Wie in der Initialisierung beschrieben wird für die UART2 der „UART2 Receive Interrupt“ im Register UART2_CR2 freigeschaltet. D.h. durch jedes Zeichen das die UART2 empfängt wird der Interrupt ausgelöst und damit die nachfolgende „Interrupt Subroutine“ „UartRxInterrupt.l“ gestartet.

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ISR  -  UART2 Receive Interrupt         (Interrupt Service Routine)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    interrupt   UartRx

UartRxInterrupt.l
   Sim                     ; Unterbinde Interrupts

Store_Char
   ld    A,UART2_SR        ; Lade UART2 Statusregister in Akku
   and   A,#$20            ; Maskiere "RXNE" Bit (Zeichen empfangen)
   jreq  No_Char           ; “IF:” "RXNE" = 0, beende Interrupt
   ld    A,URX_WRT         ; “ELSE:” > Lade URX_WRT Pointer
   inc   A                 ; Incrementiere URX_WRT Pointer
   and   A,#$3F            ; Maskiere URX_WRT Pointer auf 6 Bit(Mod 64)
   cp    A,URX_RD          ; Vergleiche WRITE mit READ Pointer
   jreq  Buff_Ovl          ; “IF:” RD-Pointer = WRT-Pointer = EQUAL
                           ; > “GOTO:” Buff_Ovl und setze Error
   clr   A                 ; “ELSE:” > Akku = “0”
   ld    XH,A              ; Lade X-Register High = “0”
   ld    A,URX_WRT         ; Lade A mit URX_WRT
   and   A,#$3F            ; Maskiere URX_WRT Pointer auf 6 Bit(Mod 64)
   ld    XL,A              ; Lade X-Register Low = URX_WRT
   ld    A,UART2_DR        ; Lade empfangenes Zeichen in Akku
   ld    (URX_BUF,X),A     ; Trage Zeichen an der nächsten freien
                           ; stelle in den URX_BUF ein
   inc   URX_WRT           ; Incrementiere URX_WRT Pointer
   jra   Store_Char        ; “GOTO:” Zeichen empfangen (Schleife)

Buff_Ovl
   bset  UART_ERR,#0       ; Setze Error Bit "0" = “Puffer Überlauf“

No_Char
   Rim                    ; Interrupt Maskierung aufheben
   Iret                   ; Interrupt Service Routine beenden

 

Schließlich und endlich muß die oben gelistete „Interrupt Service Routine“ hinsichtlich des Interrupt Vectors (Einsprung Adresse = UartRxInterrupt.l)  in die Interrupt Vektor Tabelle eingetragen werden.

Jede Vektor-Adresse besteht aus 4 Byte daher wird der Adresswert in der Notation „xxxxxxxx.l“ angegeben (“l“ steht für „long“). Das „most significant Byte“ ist aber kein Teil der Adresse da der STM8 maximal 3 Byte lange Adressen unterstützt. Daher zeigen die verbleibenden 3 Byte des Interrupt Vektors auf den Startpunkt der Interrupt Service Routine.

Die Interrupt Vektoren sind in einem fest zugeordneten Adressbereich des Flash-Speichers, der durch die Angabe des Segments `vectit` dem Assembler mitgeteilt wird. Beim STM8S105 ist der erste Vektor auf der festen Adresse 0x008000h (Reset), alle weiteren Vektoren sind jeweils um weitere 4 Byte versetzt.

;--------------------------------------------------------------------------------------
      segment 'vectit'
;--------------------------------------------------------------------------------------

Die Inhalte der Vektoren selbst stellen natürlich auch eine Adresse dar und berechnen sich aus der Summe des eingetragenen Wertes $8200.0000 + der Startadresse der Interrupt Service Routine. Da nur die geringer wertigen 3 Bytes ( = 0x00.0000h) als Adresse zählen entspricht die Vektor Adresse der Startadresse der Interrupt Service Routine allerdings wird das 4te Byte (0x82) hinzugezogen.

Vektor Interrupt Tabelle

Diese Tabelle befindet sich am Ende des „main“ Source Codes und listet die verwendeten Interrupt Vektoren die im Programm benutzt werden:

 

 

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; INTERRUPT Vectors        (STM8S105 specific)
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

       dc.l {$82000000+main}                   ; reset

       dc.l {$82000000+NonHandledInterrupt}    ; trap

       dc.l {$82000000+NonHandledInterrupt}    ; irq0 TLI

       dc.l {$82000000+NonHandledInterrupt}    ; irq1 AWU

       dc.l {$82000000+NonHandledInterrupt}    ; irq2 CLK

       dc.l {$82000000+NonHandledInterrupt}    ; irq3 Port A

       dc.l {$82000000+NonHandledInterrupt}    ; irq4 Port B

       dc.l {$82000000+NonHandledInterrupt}    ; irq5 Port C

       dc.l {$82000000+NonHandledInterrupt}    ; irq6 Port D

       dc.l {$82000000+NonHandledInterrupt}    ; irq7 Port E

       dc.l {$82000000+NonHandledInterrupt}    ; Reserved

       dc.l {$82000000+NonHandledInterrupt}    ; Reserved

       dc.l {$82000000+NonHandledInterrupt}    ; irq10 SPI

       dc.l {$82000000+NonHandledInterrupt}    ; irq11 TIM1

       dc.l {$82000000+NonHandledInterrupt}    ; irq12 TIM1 CapComp

       dc.l {$82000000+NonHandledInterrupt}    ; irq13 TIM2 update

       dc.l {$82000000+NonHandledInterrupt}    ; irq14 TIM2 CapComp

       dc.l {$82000000+NonHandledInterrupt}    ; irq15 TIM3 update

       dc.l {$82000000+NonHandledInterrupt}    ; irq16 TIM3 CapComp

       dc.l {$82000000+NonHandledInterrupt}    ; Reserved

       dc.l {$82000000+NonHandledInterrupt}    ; Reserved

       dc.l {$82000000+NonHandledInterrupt}    ; irq19 I2C

       dc.l {$82000000+NonHandledInterrupt}    ; irq20 UART2 TX (unbenutzt)

       dc.l {$82000000+UartRxInterrupt}        ; irq21 UART2 RX (UART Com)

       dc.l {$82000000+NonHandledInterrupt}    ; irq22 ADC end of conversion

       dc.l {$82000000+NonHandledInterrupt}    ; irq23 TIM4 update

       dc.l {$82000000+NonHandledInterrupt}    ; irq24 Flash

 

 

Sende Puffer Struktur

Der Sende-Puffer ist als Ring-Puffer mit 64 Byte aufgebaut. Die beiden Pointer UTX_WRT und UTX_RD zeigen jeweils auf die nächste „volle“ (RD) bzw. „leere“ (WRT) Speicherzelle.

Die Sub-Routine „Send-Char“ trägt das in der Variablen „TXCHAR“ übergebene Zeichen in den Ring-Puffer an der Stelle ein auf die UTX_WRT zeigt. Die Sub-Routine wird von der Applikation bei Bedarf direkt aufgerufen.

Die Sub-Routine „TX_UART“ wird von der Applikation bzw. von einem „Scheduler“ zyklisch aufgerufen und überträgt alle im Ring-Puffer vorhandenen Zeichen in einem Durchgang.

 

 

Empfangs Puffer Struktur

Der Empfangs-Puffer ist ebenfalls als Ring-Puffer mit 64 Byte aufgebaut. Die beiden Pointer URX_WRT und URX_RD zeigen jeweils auf die nächste „volle“ (RD) bzw. „leere“ (WRT) Speicherzelle.

Die Sub-Routine „Read_Char“ liest das nächste Zeichen (FIFO Struktur) auf welches der Pointer UTX-RD zeigt und legt dieses in der Variablen RXCHAR ab. Die Sub-Routine wird durch die Applikation aufgerufen um ein Zeichen vom Puffer abzuholen.

Die Interrup Sub-Routine UartRxInterrupt.l“ (Long Pointer) wird durch den UART Receive Interrupt aufgerufen und legt das empfangene Zeichen an der Stelle im Ring-Puffer ab auf den der Pointer URX_WRT zeigt.

 

Copyright Notiz

Copyright 2016 by Dipl.Ing.(FH) Franz Henkel

Dieses Dokument sowie dessen Inhalt, insbesondere Texte, Fotografien und Grafiken, unterliegt dem Copyright (© 2017) und sind nur mit einer schriftlicher Zustimmung des Autors, Dipl.Ing.(FH) Franz Henkel zur vollständigen oder auszugsweisen Weiterverwendung in Form einer gedruckten oder elektronischen Kopie oder Replikation bzw. einer vollständigen oder auszugsweisen Bereitstellung des Inhalts in schriftlicher, gedruckter oder elektronischer Form, zu verwenden.